package com.magiccompass.alipay.barcode.responsehandler;

import org.w3c.dom.Document;

import com.magiccompass.alipay.barcode.constants.BusinessLogicConstants;
import com.magiccompass.alipay.barcode.entity.AlipayBarcodeRefundRequest;
import com.magiccompass.alipay.barcode.entity.AlipayBarcodeRefundResponse;
import com.magiccompass.alipay.barcode.entity.MerchantTransaction;
import com.magiccompass.alipay.barcode.model.AlipayBarcodeAllResponseAJAXModel;
import com.magiccompass.alipay.barcode.model.AlipayBarcodeRefundResponseModel;
import com.magiccompass.alipay.barcode.service.AlipayBarcodeService;
import com.magiccompass.alipay.barcode.util.AlipayBarcodeResponseUtil;
import com.magiccompass.alipay.barcode.util.DateTimeUtil;
import com.magiccompass.alipay.barcode.util.DecimalUtil;
import com.magiccompass.alipay.barcode.util.XmlUtil;

public class RefundResponseHandler {
	public static AlipayBarcodeAllResponseAJAXModel handleResponse(String response,AlipayBarcodeRefundRequest abrr, AlipayBarcodeService alipayBarcodeService){
		AlipayBarcodeRefundResponseModel abcm = getResponseResult(response);
		AlipayBarcodeAllResponseAJAXModel ajaxModel = handleResultFromResultCode(abcm,abrr,alipayBarcodeService);
		return ajaxModel;
	}
	
	private static AlipayBarcodeRefundResponseModel getResponseResult(String response){
		Document xmlDoc = XmlUtil.makeXmlDocumentFromString(response);
		
		AlipayBarcodeRefundResponseModel abrr = new AlipayBarcodeRefundResponseModel();
		
		String responseIsSuccess = xmlDoc.getElementsByTagName("is_success").item(0).getTextContent();
		String sign = xmlDoc.getElementsByTagName("sign").item(0)==null?null:xmlDoc.getElementsByTagName("sign").item(0).getTextContent();
		String signType = xmlDoc.getElementsByTagName("sign_type").item(0)==null?null:xmlDoc.getElementsByTagName("sign_type").item(0).getTextContent();
		
		abrr.setIsSuccess(responseIsSuccess);
		abrr.setSign(sign);
		abrr.setSignType(signType);
		
		boolean hasSuccessResponseWithResult = false;
		
		if("T".equals(abrr.getIsSuccess())){
			String responseResultCode = xmlDoc.getElementsByTagName("result_code").item(0).getTextContent();
			abrr.setResultCode(responseResultCode);
			if("SUCCESS".equals(responseResultCode)){
				String alipayTransId = xmlDoc.getElementsByTagName("alipay_trans_id").item(0)==null?null:xmlDoc.getElementsByTagName("alipay_trans_id").item(0).getTextContent();
				String partnerTransId = xmlDoc.getElementsByTagName("partner_trans_id").item(0)==null?null:xmlDoc.getElementsByTagName("partner_trans_id").item(0).getTextContent();
				String partnerRefundId = xmlDoc.getElementsByTagName("partner_refund_id").item(0)==null?null:xmlDoc.getElementsByTagName("partner_refund_id").item(0).getTextContent();
				String refundAmount = xmlDoc.getElementsByTagName("refund_amount").item(0)==null?null:xmlDoc.getElementsByTagName("refund_amount").item(0).getTextContent();
				String currency = xmlDoc.getElementsByTagName("currency").item(0)==null?null:xmlDoc.getElementsByTagName("currency").item(0).getTextContent();
				String exchangeRate = xmlDoc.getElementsByTagName("exchange_rate").item(0)==null?null:xmlDoc.getElementsByTagName("exchange_rate").item(0).getTextContent();
				String refundAmountCNY = xmlDoc.getElementsByTagName("refund_amount_cny").item(0)==null?null:xmlDoc.getElementsByTagName("refund_amount_cny").item(0).getTextContent();
				
				abrr.setPartnerTransId(partnerTransId);
				abrr.setAlipayTransId(alipayTransId);
				abrr.setPartnerRefundId(partnerRefundId);
				abrr.setRefundAmount(DecimalUtil.createBigDecimalFromString(refundAmount));
				abrr.setCurrency(currency);
				abrr.setExchangeRate(DecimalUtil.createBigDecimalFromString(exchangeRate));
				abrr.setRefundAmountCNY(DecimalUtil.createBigDecimalFromString(refundAmountCNY));
				
				hasSuccessResponseWithResult = true;
			}else if("FAILED".equals(responseResultCode)){
				String error = xmlDoc.getElementsByTagName("error").item(0).getTextContent();
				abrr.setError(error);	
			}else if("UNKNOW".equals(responseResultCode)){
				String error = xmlDoc.getElementsByTagName("error").item(0)==null?null:xmlDoc.getElementsByTagName("error").item(0).getTextContent();
				abrr.setError(error);
			}else{
				abrr.setError("UNEXPECTED EXCEPTION");
			}
		}else if("F".equals(abrr.getIsSuccess())){
			abrr.setResultCode("-1");
			String error = xmlDoc.getElementsByTagName("error").item(0)==null?null:xmlDoc.getElementsByTagName("error").item(0).getTextContent();
			abrr.setError(error);
		}else{
			abrr.setResultCode("-2"); // ALIPAY response neither "T" nor "F"
			abrr.setError("UNEXPECTED EXCEPTION!");
		}
		if(!hasSuccessResponseWithResult){
			// follow column are mandatory, so I need give some default value
			abrr.setPartnerTransId("-1");
			abrr.setAlipayTransId("-1");
		}
		return abrr;
	}
	
	private static AlipayBarcodeAllResponseAJAXModel handleResultFromResultCode(
			AlipayBarcodeRefundResponseModel abrrm, AlipayBarcodeRefundRequest abrreq, AlipayBarcodeService alipayBarcodeService){
		
		AlipayBarcodeAllResponseAJAXModel abpram = new AlipayBarcodeAllResponseAJAXModel();
		MerchantTransaction mt = abrreq.getMerchantTransaction();
		if("T".equals(abrrm.getIsSuccess())){  // request success accept by ALIPAY
			String resultCode = abrrm.getResultCode();
			if("SUCCESS".equals(resultCode)){
				abrreq.setStatus("S");
				mt.setStatus("E");
				abpram.setResponseResultCode(resultCode);
				abpram.setResponseResultReason("Please continue.");
			}else if("FAILED".equals(resultCode)){
				abrreq.setStatus("F");
				//mt.setStatus("F"); // if reverse failed means nothing happened
				abpram.setResponseResultCode(resultCode);
				abpram.setResponseResultReason(abrrm.getError());
			}else if("UNKNOW".equals(resultCode)){
				abrreq.setStatus("U");
				mt.setStatus("U");
				//TODO need reverse payment(offline) or query(online) 
				// 2016-03-22 confirm: offline mode
				abpram.setResponseResultCode(resultCode);
				abpram.setResponseResultReason(abrrm.getError());				
			}	
		}else if("F".equals(abrrm.getIsSuccess())){ // request failed accept by ALIPAY, maybe parameter error
			abrreq.setStatus("D");
			mt.setStatus("D");
			abpram.setResponseResultCode("ERROR");
			abpram.setResponseResultReason(abrrm.getError());
		}else{
			abrreq.setStatus("D");
			mt.setStatus("D");
			abpram.setResponseResultCode("UNEXPECTED");
			abpram.setResponseResultReason("Unexpected error happened. Please contact support.");
		}
		mt.setUpdateby(BusinessLogicConstants.SYSTEM_CREATOR_ID);
		mt.setUpdateTime(DateTimeUtil.getCurrentTimestamp());
		abrreq.setMerchantTransaction(mt);
		abrreq.setUpdateby(BusinessLogicConstants.SYSTEM_CREATOR_ID);
		abrreq.setUpdateTime(DateTimeUtil.getCurrentTimestamp());
		alipayBarcodeService.save(abrreq);
		
		AlipayBarcodeRefundResponse abcres = AlipayBarcodeResponseUtil.createAlipayBarcodeRefundReponseEntityFromModelAndRequest(abrrm, abrreq);
		alipayBarcodeService.save(abcres);
		
		return abpram;
	}
	
	public static void main(String[] args){
		AlipayBarcodeRefundResponseModel abprm = getResponseResult(RESULT_SUCCESS_4_TEST);
		System.out.println(abprm);

	}
	
	public static final String RESULT_SUCCESS_4_TEST = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><alipay><is_success>T</is_success><request><param name=\"trans_create_time\">20160323103315</param><param name=\"identity_code_type\">barcode</param><param name=\"alipay_seller_id\">2088021966645500</param><param name=\"sign_type\">RSA</param><param name=\"trans_amount\">61.87</param><param name=\"trans_name\">PAYMENT_BY_ALIPAY_BARCODE</param><param name=\"partner_trans_id\">104</param><param name=\"buyer_identity_code\">123456789012345678</param><param name=\"currency\">AUD</param><param name=\"sign\">T0cPCjvrtoOMgMx5kztMXJj1k7BquXSszD0yXK9IoGYt/PwDYK6UUZiMWN41QUpjGZD1uDMKJWhtRMfw7Zwsd5/ieQ3ODB/OMy6FN6zCrztUr4v0rpPvyCRTI9DWR8iVqPay64lT3335AbvqD3wp2zqw97xbQ9e2ykmH/7VVrlQ=</param><param name=\"_input_charset\">UTF-8</param><param name=\"biz_product\">OVERSEAS_MBARCODE_PAY</param><param name=\"service\">alipay.acquire.overseas.spot.pay</param><param name=\"partner\">2088021966645500</param></request><response><alipay><alipay_trans_id>2011091703338463</alipay_trans_id><partner_trans_id>201311221000000002</partner_trans_id><alipay_buyer_user_id>2088102130896433</alipay_buyer_user_id><alipay_buyer_login_id>cao***@126.com</alipay_buyer_login_id><alipay_pay_time>20131120155823</alipay_pay_time><exchange_rate>6.0939</exchange_rate><currency>AUD</currency><trans_amount>39.25</trans_amount><trans_amount_CNY>239.19</trans_amount_CNY><result_code>SUCCESS</result_code></alipay></response><sign>D/UTFJt5yh3rxNXSE5botyzpyv9vDe/QbJpLgJ98j3j9HtGcVHpUtPyFr/3ZuVt3VFJ4XI9v41/wqe1qBEeTjffg4hmXOWF1nc8+ePfZNi883Qgl7a4d3hzcXzr9j1lsK33cJeruLEBeQOiu7umd3jPBHdBSBx9qt7DbeLgbtKM=</sign><sign_type>RSA</sign_type></alipay>";
	public static final String RESULT_FAILED_4_TEST = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><alipay><is_success>T</is_success><request><param name=\"trans_create_time\">20160323103315</param><param name=\"identity_code_type\">barcode</param><param name=\"alipay_seller_id\">2088021966645500</param><param name=\"sign_type\">RSA</param><param name=\"trans_amount\">61.87</param><param name=\"trans_name\">PAYMENT_BY_ALIPAY_BARCODE</param><param name=\"partner_trans_id\">104</param><param name=\"buyer_identity_code\">123456789012345678</param><param name=\"currency\">AUD</param><param name=\"sign\">T0cPCjvrtoOMgMx5kztMXJj1k7BquXSszD0yXK9IoGYt/PwDYK6UUZiMWN41QUpjGZD1uDMKJWhtRMfw7Zwsd5/ieQ3ODB/OMy6FN6zCrztUr4v0rpPvyCRTI9DWR8iVqPay64lT3335AbvqD3wp2zqw97xbQ9e2ykmH/7VVrlQ=</param><param name=\"_input_charset\">UTF-8</param><param name=\"biz_product\">OVERSEAS_MBARCODE_PAY</param><param name=\"service\">alipay.acquire.overseas.spot.pay</param><param name=\"partner\">2088021966645500</param></request><response><alipay><error>INVALID_PARAMETER</error><result_code>FAILED</result_code></alipay></response><sign>D/UTFJt5yh3rxNXSE5botyzpyv9vDe/QbJpLgJ98j3j9HtGcVHpUtPyFr/3ZuVt3VFJ4XI9v41/wqe1qBEeTjffg4hmXOWF1nc8+ePfZNi883Qgl7a4d3hzcXzr9j1lsK33cJeruLEBeQOiu7umd3jPBHdBSBx9qt7DbeLgbtKM=</sign><sign_type>RSA</sign_type></alipay>";
	public static final String RESULT_UNKNOWN_4_TEST = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><alipay><is_success>T</is_success><request><param name=\"trans_create_time\">20160323103315</param><param name=\"identity_code_type\">barcode</param><param name=\"alipay_seller_id\">2088021966645500</param><param name=\"sign_type\">RSA</param><param name=\"trans_amount\">61.87</param><param name=\"trans_name\">PAYMENT_BY_ALIPAY_BARCODE</param><param name=\"partner_trans_id\">104</param><param name=\"buyer_identity_code\">123456789012345678</param><param name=\"currency\">AUD</param><param name=\"sign\">T0cPCjvrtoOMgMx5kztMXJj1k7BquXSszD0yXK9IoGYt/PwDYK6UUZiMWN41QUpjGZD1uDMKJWhtRMfw7Zwsd5/ieQ3ODB/OMy6FN6zCrztUr4v0rpPvyCRTI9DWR8iVqPay64lT3335AbvqD3wp2zqw97xbQ9e2ykmH/7VVrlQ=</param><param name=\"_input_charset\">UTF-8</param><param name=\"biz_product\">OVERSEAS_MBARCODE_PAY</param><param name=\"service\">alipay.acquire.overseas.spot.pay</param><param name=\"partner\">2088021966645500</param></request><response><alipay><result_code>UNKNOW</result_code></alipay></response><sign>D/UTFJt5yh3rxNXSE5botyzpyv9vDe/QbJpLgJ98j3j9HtGcVHpUtPyFr/3ZuVt3VFJ4XI9v41/wqe1qBEeTjffg4hmXOWF1nc8+ePfZNi883Qgl7a4d3hzcXzr9j1lsK33cJeruLEBeQOiu7umd3jPBHdBSBx9qt7DbeLgbtKM=</sign><sign_type>RSA</sign_type></alipay>";
	public static final String RESULT_FAILEDFAIED_4_TEST = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><alipay><is_success>F</is_success><error>ILLEGAL_SIGN</error><sign>D/UTFJt5yh3rxNXSE5botyzpyv9vDe/QbJpLgJ98j3j9HtGcVHpUtPyFr/3ZuVt3VFJ4XI9v41/wqe1qBEeTjffg4hmXOWF1nc8+ePfZNi883Qgl7a4d3hzcXzr9j1lsK33cJeruLEBeQOiu7umd3jPBHdBSBx9qt7DbeLgbtKM=</sign><sign_type>RSA</sign_type></alipay>";
}
